#include "include/ivc.h"
#include <linux/fs.h>
// #include <fcntl.h>

bool receive_msg(struct msg_data *msg) {
    struct {
        u64 hvc_fid;
        u64 event;
        u64 src;
        u64 idx;
        u64 fin;
    } usr_arg;
    if (msg->src >= 4) {
        return false;
    }
    if (msg->idx != shyper_dev.receive_idx[msg->src] + 1) {
        return false;
    }
    usr_arg.hvc_fid = HVC_IVC;
    usr_arg.event = HVC_IVC_SEND_MSG;
    usr_arg.src = msg->src;
    usr_arg.idx = msg->idx;
    usr_arg.fin = msg->fin;
    queue_push(shyper_dev.usr_arg_queue, &usr_arg, sizeof(usr_arg));
    send_signal(SIGIVC);
    return true;
}

bool test_receive_msg(struct msg_data *msg) {
    struct {
        u64 hvc_fid;
        u64 event;
        u64 src;
        u64 size;
        u64 page_num;
    } usr_arg;
    if(msg -> src >= 4){
        return false;
    } 
    // if(msg->idx != shyper_dev.receive_idx[msg->src] + 1){
    //     return false;
    // }
    usr_arg.hvc_fid = HVC_IVC;
    usr_arg.event = msg->event;
    usr_arg.size = msg->size;
    usr_arg.src = msg->src;
    usr_arg.page_num = msg->idx;
    queue_push(shyper_dev.usr_arg_queue,&usr_arg,sizeof(usr_arg));
    send_signal(SIGIVC);
    return true;
}

bool receive_ack(void *ack) {
    struct {
        u64 fid;
        u64 event;
        u64 src;
        u64 idx;
        u64 fin;
    } *arg = ack;

    INFO("receive ack[%d] from vm[%d]", (u32)arg->idx, (u32)arg->src);

    if (arg->fin) {
        shyper_dev.send_idx[arg->src] = -1;
    } else if (arg->idx == (shyper_dev.send_idx[arg->src] + 1)) {
        shyper_dev.send_idx[arg->src] = arg->idx;
    }

    queue_push(shyper_dev.usr_arg_queue, arg, sizeof(*arg));
    send_signal(SIGIVC);

    return true;
}